package megrez.job.custom.component;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import megrez.job.custom.domain.Config;

/**
 * 任务
 * 
 * @author Lucky Yang
 * @since 2.6.9
 */
@Getter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Task {
    @EqualsAndHashCode.Include
    private final Config config;
    private final Monitor monitor;

    private Task(Monitor monitor, Config config) {
        this.monitor = monitor;
        this.config = config;
    }

    public Task(Task task) {
        this(new Monitor(task.getMonitor()), task.getConfig());
    }

    private void validate() {
        boolean hasText = StringUtils.hasText(config.getClassName())
                && StringUtils.hasText(config.getMethodName())
                && StringUtils.hasText(config.getCronExpression());
        if (!hasText) {
            throw new IllegalArgumentException("Config's filed: className, methotName, cronExpression must have value");
        }
    }

    @Override
    public String toString() {
        return "Task [ id = " + config.getId() +
                ", className = " + config.getClassName() +
                ", methodName = " + config.getMethodName() +
                ", cronExpression = " + config.getCronExpression() +
                ", state = " + monitor.getState() +
                ", startUpTime = " + monitor.getStartUpTime() +
                ", lastRunTime = " + monitor.getLastRunTime() +
                "]";
    }

    public static Task of(Config config) {
        Assert.notNull(config, "config must not be null");

        Task rslt = new Task(new Monitor(), config);
        rslt.validate();
        return rslt;
    }
}
